home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 21
/
CU Amiga Magazine's Super CD-ROM 21 (1998)(EMAP Images)(GB)[!][issue 1998-04].iso
/
CUCD
/
Magazine
/
C_Tutorial
/
Part-3
/
gadgets1a.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-27
|
7KB
|
276 lines
#include<exec/libraries.h>
#include<intuition/intuition.h>
#include<utility/tagitem.h>
#include<graphics/text.h>
#include<graphics/rastport.h>
#include<intuition/screens.h>
#include<libraries/gadtools.h>
#include<string.h>
#include<stdio.h>
#include<clib/exec_protos.h>
#include<clib/graphics_protos.h>
#include<clib/intuition_protos.h>
#include<clib/layers_protos.h>
#include<clib/gadtools_protos.h>
/* The library base global variables */
/* (The different style of opening libraries requires these to be initialised to NULL) */
struct Library* GfxBase = NULL;
struct Library* IntuitionBase = NULL;
struct Library* LayersBase = NULL;
struct Library* GadToolsBase = NULL;
/* Need to give prototypes for our functions */
void handleIDCMP(struct Window*);
int setClip(struct Window*);
void removeClip(struct Window*);
void setupWindow();
void createWindow(struct Gadget*);
int openLibs();
void closeLibs();
/* Some constants for the size of the window */
#define MYWIN_WIDTH (400)
#define MYWIN_HEIGHT (200)
/* Some constants for the position and size of our gadget */
#define MYGAD_LEFT (10)
#define MYGAD_TOP (5)
#define MYGAD_WIDTH (80)
#define MYGAD_HEIGHT (12)
#define MYGAD_TEXT "Next Pen"
#define MYGAD_ID (0)
/* The top gap required around the gadgets */
#define MYTOPGAP (30)
/* The start of the program */
void main()
{
/* Use a different style of opening libraries... */
if(openLibs())
{
/* Now do the real work */
setupWindow();
}
/* Matched call to close libraries */
closeLibs();
}
/* The open library code is very symmetrical, so we could use a macro: */
#define TryOpenLib(base,lib,vers) \
if((base = OpenLibrary((lib),(vers))) == NULL) \
{ \
printf("Error: could not open " lib "\n"); \
return FALSE; \
}
/* Try to open all the libraries -- return TRUE on success */
int openLibs()
{
TryOpenLib(GfxBase, "graphics.library", 37);
TryOpenLib(IntuitionBase, "intuition.library", 37);
TryOpenLib(LayersBase, "layers.library", 37);
TryOpenLib(GadToolsBase, "gadtools.library", 37);
return TRUE;
}
/* Close any open library */
void closeLibs()
{
if(GadToolsBase)
CloseLibrary(GadToolsBase);
if(LayersBase)
CloseLibrary(LayersBase);
if(IntuitionBase)
CloseLibrary(IntuitionBase);
if(GfxBase)
CloseLibrary(GfxBase);
}
/* Setup the window -- do the GadTools stuff */
void setupWindow()
{
struct Screen* scr;
/* We'll copy the visual information for the default public screen */
/* (usually, this is the Workbench screen) */
if(scr = LockPubScreen(NULL))
{
APTR vinfo;
/* Get the visual info so GadTools can render the gadgets nicely */
if(vinfo = GetVisualInfo(scr, TAG_DONE))
{
/* We can initialise glist in its declaration */
struct Gadget* glist = NULL;
struct Gadget* gad;
int offtop, offleft;
struct NewGadget newgad;
/* Initialised structure declaration: describes 8pt Topaz font */
struct TextAttr topazFont = { "topaz.font", 8, 0, 0, };
/* Start a GadTools gadget list */
/* (Don't need to check gad, since CreateGadget() will fail if gad is NULL) */
gad = CreateContext(&glist);
/* The offsets of our window borders */
offleft = scr->WBorLeft;
offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
/* Setup our first gadget */
newgad.ng_TextAttr = &topazFont;
newgad.ng_VisualInfo = vinfo;
newgad.ng_LeftEdge = MYGAD_LEFT + offleft;
newgad.ng_TopEdge = MYGAD_TOP + offtop;
newgad.ng_Width = MYGAD_WIDTH;
newgad.ng_Height = MYGAD_HEIGHT;
newgad.ng_GadgetText = MYGAD_TEXT;
newgad.ng_GadgetID = MYGAD_ID;
newgad.ng_Flags = 0;
/* Now create it and add it to our list */
if(gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_DONE))
createWindow(glist);
else
printf("Error: could not create gadget(s)\n");
/* Free the gadget */
FreeGadgets(glist);
FreeVisualInfo(vinfo);
}
else
printf("Error: could not get visual info\n");
UnlockPubScreen(NULL, scr);
}
else
printf("Error: could not lock public screen\n");
}
/* Actually open the window, in the normal way */
void createWindow(struct Gadget* glist)
{
struct Window* win;
/* Open our window */
if(win = OpenWindowTags(NULL,
WA_Width, MYWIN_WIDTH,
WA_Height, MYWIN_HEIGHT,
WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_REPORTMOUSE,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | BUTTONIDCMP | IDCMP_REFRESHWINDOW,
WA_Gadgets, glist,
TAG_DONE, 0))
{
/* If window opened, set clip region */
if(setClip(win))
{
/* Let GadTools refresh its bits of the window */
GT_RefreshWindow(win, NULL);
/* Now handle messages */
handleIDCMP(win);
removeClip(win);
}
else
printf("Error: could not set clip region on window\n");
CloseWindow(win);
}
else
printf("Error: could not open window\n");
}
/* Our message handling code */
void handleIDCMP(struct Window* win)
{
char* text = "Hello World!";
int going = TRUE;
int drawing = FALSE;
UBYTE pen = 1;
SetAPen(win->RPort, pen);
/* Set the drawing mode to draw only the foreground of text, not the background */
SetDrMd(win->RPort, JAM1);
while(going)
{
struct IntuiMessage* intuimsg;
/* Wait for messages to arrive */
WaitPort(win->UserPort);
/* Messages have arrived: loop through all of them */
while(intuimsg = GT_GetIMsg(win->UserPort))
{
/* Act on this message... */
switch(intuimsg->Class)
{
case IDCMP_MOUSEBUTTONS:
switch(intuimsg->Code)
{
case SELECTDOWN:
drawing = TRUE;
break;
case SELECTUP:
drawing = FALSE;
break;
}
/* break; omitted so we draw on click, too */
case IDCMP_MOUSEMOVE:
/* Don't draw on top gap which holds gadget */
if(drawing && intuimsg->MouseY > win->BorderTop+MYTOPGAP)
{
Move(win->RPort, intuimsg->MouseX, intuimsg->MouseY);
Text(win->RPort, text, strlen(text));
}
break;
case IDCMP_CLOSEWINDOW:
going = FALSE;
break;
case IDCMP_REFRESHWINDOW:
/* You *MUST* remember to ask for and handle these refresh messages */
GT_BeginRefresh(win);
GT_EndRefresh(win, TRUE);
break;
case IDCMP_GADGETUP:
/* Our button was clicked! Set foreground to next pen colour */
pen++;
SetAPen(win->RPort, pen);
break;
}
/* Reply when finished with message */
GT_ReplyIMsg(intuimsg);
}
}
}
/* Set a clip region on internal part of window */
int setClip(struct Window* win)
{
/* Make a new region */
struct Region* reg;
if(reg = NewRegion())
{
/* Make a rectangle that describes the inside of the window */
struct Rectangle rect;
rect.MinX = win->BorderLeft;
rect.MinY = win->BorderTop;
rect.MaxX = win->Width - win->BorderRight - 1;
rect.MaxY = win->Height - win->BorderBottom - 1;
/* Make the region equal to this rectangle */
if(OrRectRegion(reg, &rect))
{
/* Set the clip region on the window's layer */
InstallClipRegion(win->WLayer, reg);
/* Say we succeeded */
return TRUE;
}
else
{
/* Failed to set region, so delete it */
DisposeRegion(reg);
}
}
/* If we get this far they we've failed */
return FALSE;
}
/* Remove the clip region from a window */
void removeClip(struct Window* win)
{
struct Region* reg;
if(reg = InstallClipRegion(win->WLayer, NULL))
{
/* If a clip region is installed it's our new one, so delete it */
DisposeRegion(reg);
}
}